package com.example.musicplayer.adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.example.musicplayer.R;
import com.example.musicplayer.dialogTools.NormalAlertDialog;
import com.example.musicplayer.user.User;
import com.example.musicplayer.user.UserInfo;

import java.util.ArrayList;
import java.util.List;

public class UserManageAdapter extends SlideListViewAdapter {
    public static final int MODE_NORMAL = 1;
    public static final int MODE_SELECT = 2;
    private int mMode;
    private final List<UserInfo> mInfoList;
    private final List<Boolean> mSelectedList;
    private Callback mCallback;
    private final MyHandler mHandler;

    private static class MyHandler extends Handler {

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.obj instanceof BitmapRequest) {
                BitmapRequest request = (BitmapRequest) msg.obj;
                request.mImageView.setImageBitmap(request.mBitmap);
            }
        }
    }

    public interface Callback {
        void onItemSelectedStateChanged(int position, boolean isSelected);

        void onDeleteUser(List<Integer> userIdList);
    }

    public UserManageAdapter(Context context, int mode, ListView listView) {
        super(context, listView);
        mMode = mode;
        mInfoList = User.getInstance().getAllUserInfo();
        mSelectedList = new ArrayList<Boolean>();
        for (int i = 0; i < mInfoList.size(); i++) {
            mSelectedList.add(false);
        }
        mHandler = new MyHandler();
    }

    public void setCallback(Callback callback) {
        mCallback = callback;
    }

    public void setMode(int mode) {
        mMode = mode;
        if (mMode == MODE_NORMAL) {
            for (int i = 0; i < mSelectedList.size(); i++) {
                mSelectedList.set(i, false);
            }
        }
        notifyDataSetChanged();
    }

    public int getMode() {
        return mMode;
    }

    public void selectAll(boolean selectAll) {
        for (int i = 0; i < mSelectedList.size(); i++) {
            mSelectedList.set(i, selectAll);
        }
        notifyDataSetChanged();
    }

    public boolean isAllSelected() {
        for (int i = 0; i < mSelectedList.size(); i++) {
            if (!mSelectedList.get(i)) {
                return false;
            }
        }
        return true;
    }

    public void deleteSelectedUser() {
        final List<Integer> idList = new ArrayList<Integer>();
        for (int i = 0; i < mSelectedList.size(); i++) {
            if (mSelectedList.get(i)) {
                idList.add(mInfoList.get(i).mUserId);
            }
        }
        if (idList.size() > 0) {
            final NormalAlertDialog normalAlertDialog = new NormalAlertDialog(mContext
                    , mContext.getResources().getString(R.string.prompt)
                    , mContext.getResources().getString(R.string.user_manage_delete_multi_dialog_text));
            normalAlertDialog.getConfirm().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //delete user and data
                    if (mCallback != null) {
                        mCallback.onDeleteUser(idList);
                    }
                    for (int i = 0; i < mSelectedList.size(); i++) {
                        if (mSelectedList.get(i)) {
                            mSelectedList.remove(i);
                            mInfoList.remove(i);
                            i--;
                        }
                    }
                    UserManageAdapter.this.notifyDataSetChanged();
                    normalAlertDialog.dismiss();
                }
            });
            normalAlertDialog.show();
        }
    }

    @Override
    public int getCount() {
        return mInfoList.size();
    }

    @Override
    public Object getItem(int position) {
        return mInfoList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @SuppressLint("InflateParams")
    @Override
    protected View bindView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.user_manage_item_view, null);
            convertView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    (int) mContext.getResources().getDimension(R.dimen.user_manage_item_height)));
            viewHolder.mSingleDelete = convertView.findViewById(R.id.single_delete_area);
            viewHolder.mSingleSelect = convertView.findViewById(R.id.single_select);
            viewHolder.mDeleteView = convertView.findViewById(R.id.delete_user);
            viewHolder.mUserName = convertView.findViewById(R.id.user_name);
            viewHolder.mUserEmail = convertView.findViewById(R.id.user_email);
            viewHolder.mUserPhoto = convertView.findViewById(R.id.user_photo);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        //setup
        final UserInfo userInfo = mInfoList.get(position);
        if (userInfo != null) {
            //get request to update image
            final BitmapRequest request = new BitmapRequest();
            request.mImageView = viewHolder.mUserPhoto;
            new Thread() {
                @Override
                public void run() {
                    request.mBitmap = User.getUserPhoto(userInfo.mUserPhoto);
                    Message msg = mHandler.obtainMessage();
                    msg.obj = request;
                    mHandler.sendMessage(msg);
                }
            }.start();
            //update other info
            viewHolder.mUserName.setText(userInfo.mUserName);
            viewHolder.mUserEmail.setText(userInfo.mUserEmail);
            viewHolder.mSingleSelect.setSelected(mSelectedList.get(position));
            //single delete of user
            viewHolder.mSingleDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    itemDelete(position);
                }
            });
            //single select of user
            convertView.findViewById(R.id.single_select_area).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    boolean preState = viewHolder.mSingleSelect.isSelected();
                    viewHolder.mSingleSelect.setSelected(!preState);
                    itemSelectedChanged(position, !preState);
                }
            });
            //right view to delete user
            viewHolder.mDeleteView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    itemDelete(position);
                }
            });
        }
        //display mode
        convertView.findViewById(R.id.single_select_area).setVisibility(mMode == MODE_SELECT ? View.VISIBLE : View.GONE);
        return convertView;
    }

    private void itemDelete(final int position) {
        final NormalAlertDialog normalAlertDialog = new NormalAlertDialog(mContext
                , mContext.getResources().getString(R.string.prompt)
                , mContext.getResources().getString(R.string.user_manage_delete_dialog_text));
        normalAlertDialog.getConfirm().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int deleteId = mInfoList.get(position).mUserId;
                mInfoList.remove(position);
                mSelectedList.remove(position);
                UserManageAdapter.this.notifyDataSetChanged();
                normalAlertDialog.dismiss();
                //delete user and data
                List<Integer> idList = new ArrayList<Integer>();
                idList.add(deleteId);
                if (mCallback != null) {
                    mCallback.onDeleteUser(idList);
                }
            }
        });
        normalAlertDialog.show();
    }

    private void itemSelectedChanged(int position, boolean selected) {
        mSelectedList.set(position, selected);
        if (mCallback != null) {
            mCallback.onItemSelectedStateChanged(position, selected);
        }
    }

    private static class BitmapRequest {
        ImageView mImageView;
        Bitmap mBitmap;
    }

    private static class ViewHolder {
        View mSingleDelete;
        View mSingleSelect;
        View mDeleteView;
        TextView mUserName;
        TextView mUserEmail;
        ImageView mUserPhoto;
    }
}